package com.example.ymm.modules1.service.dd;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkdrive_1_0.Client;
import com.aliyun.dingtalkdrive_1_0.models.*;
import com.aliyun.dingtalkstorage_1_0.models.CommitFileResponse;
import com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoResponse;
import com.aliyun.dingtalkstorage_2_0.models.UpdatePermissionResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.example.ymm.exception.YmException;
import com.example.ymm.util.DateKit;
import com.example.ymm.util.RedisKeyManager;
import com.example.ymm.util.RedisUtil;
import com.example.ymm.util.UtilValidate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class DingFileService {

    /**
     * NiP8zU3JbIkeVshDlPJWaiSgiEiE   邵跃明
     * FiimGbp9iiajIiE                刘庆峰
     */
    String unionId="FiimGbp9iiajIiE";

    String spaceId="24904995948";

    String corpId="ding2e2011827f67ec7d35c2f4657eb6378f";

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    AccessTokenService2 accessTokenService;

    public  com.aliyun.dingtalkdrive_1_0.Client createClient() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkdrive_1_0.Client(config);
    }

    /**
     * 创建客户端2.0
     * @return
     * @throws Exception
     */
    public  com.aliyun.dingtalkstorage_2_0.Client createClient_2() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkstorage_2_0.Client(config);
    }

    public  com.aliyun.dingtalkstorage_1_0.Client createClient_1() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkstorage_1_0.Client(config);
    }


    /**
     * 创建钉盘共享空间
     */
    public void createSpaceFn(){
        String accessToken = accessTokenService.getAccessToken();


        AddSpaceHeaders addSpaceHeaders = new AddSpaceHeaders();
        addSpaceHeaders.xAcsDingtalkAccessToken = accessToken;
        AddSpaceRequest addSpaceRequest = new AddSpaceRequest()
                .setName("恒丽书城图书")
                .setUnionId(unionId);
        try {
            Client client = createClient();
            AddSpaceResponse addSpaceResponse = client.addSpaceWithOptions(addSpaceRequest, addSpaceHeaders, new RuntimeOptions());
            System.out.println("----spaceId:"+addSpaceResponse.getBody().spaceId);
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                throw new RuntimeException(err.message);
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                throw new RuntimeException(err.message);
            }

        }
    }


    //查询盯盘空间
    public void querySpaceList(){
        String accessToken = accessTokenService.getAccessToken();

        ListSpacesHeaders listSpacesHeaders = new ListSpacesHeaders();
        listSpacesHeaders.xAcsDingtalkAccessToken = accessToken;
        ListSpacesRequest listSpacesRequest = new ListSpacesRequest()
                .setUnionId(unionId)
                .setSpaceType("org")
              //  .setNextToken("2CMlB97VtVJWfoVliPIXPUQiEiE")
                .setMaxResults(50);
        try {
            com.aliyun.dingtalkdrive_1_0.Client client = createClient();

            ListSpacesResponse listSpacesResponse = client.listSpacesWithOptions(listSpacesRequest, listSpacesHeaders, new RuntimeOptions());
            List<ListSpacesResponseBody.ListSpacesResponseBodySpaces> spaces = listSpacesResponse.getBody().getSpaces();
            for(ListSpacesResponseBody.ListSpacesResponseBodySpaces sp: spaces){
                System.out.println("--spaceId:"+sp.getSpaceId()+"--spaceName:"+sp.getSpaceName()+"--createTime:"+sp.getCreateTime());
            }

        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                throw new YmException(err.message);
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                throw new YmException(err.message);
            }

        }
    }

    /**
     * 删除钉盘空间
     * @param spaceId
     */
    public void deleteSpacesFn(String spaceId){
        String accessToken = accessTokenService.getAccessToken();

        DeleteSpaceHeaders deleteSpaceHeaders = new DeleteSpaceHeaders();
        deleteSpaceHeaders.xAcsDingtalkAccessToken = accessToken;
        DeleteSpaceRequest deleteSpaceRequest = new DeleteSpaceRequest()
                .setUnionId(unionId);
        try {
            com.aliyun.dingtalkdrive_1_0.Client client = createClient();

            client.deleteSpaceWithOptions(spaceId, deleteSpaceRequest, deleteSpaceHeaders, new RuntimeOptions());
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        }
    }


    /**
     * 获取上传文件信息
     */
    public com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoResponseBody  getFileInfo(MultipartFile file){
        String originalFilename = file.getOriginalFilename();
        String dates = DateKit.dateFormat(new Date(), "yyyy-MM-dd");

        com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoResponseBody responseBody=null;

        String accessToken = accessTokenService.getAccessToken();

        com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoHeaders getFileUploadInfoHeaders = new com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoHeaders();
        getFileUploadInfoHeaders.xAcsDingtalkAccessToken = accessToken;
        com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoRequest.GetFileUploadInfoRequestOptionPreCheckParam optionPreCheckParam = new com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoRequest.GetFileUploadInfoRequestOptionPreCheckParam()
                .setMd5(DigestUtils.md5Hex(originalFilename))
                .setSize(file.getSize())
                .setParentId("0")
                .setName(file.getOriginalFilename());
        com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoRequest.GetFileUploadInfoRequestOption option = new com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoRequest.GetFileUploadInfoRequestOption()
                .setStorageDriver("DINGTALK")
                .setPreCheckParam(optionPreCheckParam)
                .setPreferRegion("SHENZHEN")
                .setPreferIntranet(true);
        com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoRequest getFileUploadInfoRequest = new com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoRequest()
                .setUnionId(unionId)
                .setProtocol("HEADER_SIGNATURE")
                .setMultipart(false)
                .setOption(option);
        try {
            com.aliyun.dingtalkstorage_1_0.Client client = createClient_1();

            GetFileUploadInfoResponse fileUploadInfoWithOptions = client.getFileUploadInfoWithOptions(spaceId, getFileUploadInfoRequest, getFileUploadInfoHeaders, new RuntimeOptions());
            responseBody = fileUploadInfoWithOptions.getBody();
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                throw new YmException(err.message);
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                throw new YmException(err.message);
            }

        }

        return responseBody;
    }


    /**
     * 文件上传到钉盘
     * @param file
     * @return
     */
    public String uploadFileFn(MultipartFile file){
        com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoResponseBody responseBody = getFileInfo(file);
        uploadFileToDing(responseBody,file);
        JSONObject map = addFileToDing(responseBody, file);
        addFileUserPermissions(map);
        return map.toString();
    }

    /**
     * 文件上传到钉盘
     */
    public void uploadFileToDing(com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoResponseBody responseBody,MultipartFile file){

        try{
            // 从接口返回信息中拿到resourceUrls
            String resourceUrl = responseBody.getHeaderSignatureInfo().resourceUrls.get(0);
            // 从接口返回信息中拿到headers
            Map<String, String> headers = responseBody.getHeaderSignatureInfo().headers;
            URL url = new URL(resourceUrl);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            if (headers != null) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    connection.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            connection.setDoOutput(true);
            connection.setRequestMethod("PUT");
            connection.setUseCaches(false);
            connection.setReadTimeout(10000);
            connection.setConnectTimeout(10000);
            connection.connect();
            OutputStream out = connection.getOutputStream();
            InputStream is = file.getInputStream();
            byte[] b =new byte[1024];
            int temp;
            while ((temp=is.read(b))!=-1){
                out.write(b,0,temp);
            }
            out.flush();
            out.close();
            int responseCode = connection.getResponseCode();
            connection.disconnect();
            if (responseCode == 200) {
                System.out.println("上传成功");
            } else {
                System.out.println("上传失败");
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
            throw new YmException(e.getMessage());
        }



    }

    /**
     * 添加文件
     * @param
     */
    public JSONObject addFileToDing(com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoResponseBody responseBody,MultipartFile file){
        AddFileHeaders addFileHeaders = new AddFileHeaders();
        Map<String, Object> result=null;

        JSONObject json=null;
        String accessToken = accessTokenService.getAccessToken();
        com.aliyun.dingtalkstorage_1_0.models.CommitFileHeaders commitFileHeaders = new com.aliyun.dingtalkstorage_1_0.models.CommitFileHeaders();
        commitFileHeaders.xAcsDingtalkAccessToken = accessToken;
        com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest.CommitFileRequestOptionAppProperties optionAppProperties0 = new com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest.CommitFileRequestOptionAppProperties()
                .setName("属性1")
                .setValue("属性值1")
                .setVisibility("PUBLIC");
        com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest.CommitFileRequestOption option = new com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest.CommitFileRequestOption()
                .setSize(file.getSize())
                .setConflictStrategy("OVERWRITE")
                .setAppProperties(java.util.Arrays.asList(
                        optionAppProperties0
                ));
        com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest commitFileRequest = new com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest()
                .setUnionId(unionId)
                .setUploadKey(responseBody.getUploadKey())
                .setName(file.getOriginalFilename())
                .setParentId("0")
                .setOption(option);
        try {
            com.aliyun.dingtalkstorage_1_0.Client client =createClient_1();

            CommitFileResponse commitFileResponse = client.commitFileWithOptions(spaceId, commitFileRequest, commitFileHeaders, new RuntimeOptions());
            json=new JSONObject(commitFileResponse.getBody().getDentry().toMap());
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                throw new YmException(err.message);
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                throw new YmException(err.message);
            }

        }
        return json;
    }


    /**
     * 给文件添加权限-不然其他人访问不了
     * @param jsonObject
     */
    public void addFileUserPermissions(JSONObject jsonObject){
        String accessToken = accessTokenService.getAccessToken();



        com.aliyun.dingtalkstorage_2_0.models.AddPermissionHeaders addPermissionHeaders = new com.aliyun.dingtalkstorage_2_0.models.AddPermissionHeaders();
        addPermissionHeaders.xAcsDingtalkAccessToken = accessToken;
        com.aliyun.dingtalkstorage_2_0.models.AddPermissionRequest.AddPermissionRequestOption option = new com.aliyun.dingtalkstorage_2_0.models.AddPermissionRequest.AddPermissionRequestOption()
                .setDuration(3600L);
        com.aliyun.dingtalkstorage_2_0.models.AddPermissionRequest.AddPermissionRequestMembers members0 = new com.aliyun.dingtalkstorage_2_0.models.AddPermissionRequest.AddPermissionRequestMembers()
                .setType("ORG")
                .setId(corpId)
                .setCorpId(corpId);
        com.aliyun.dingtalkstorage_2_0.models.AddPermissionRequest addPermissionRequest = new com.aliyun.dingtalkstorage_2_0.models.AddPermissionRequest()
                .setUnionId(unionId)
                .setRoleId("DOWNLOADER")
                .setMembers(java.util.Arrays.asList(
                        members0
                ))
                .setOption(option);
        try {
            com.aliyun.dingtalkstorage_2_0.Client client = createClient_2();
            client.addPermissionWithOptions(jsonObject.getString("uuid"), addPermissionRequest, addPermissionHeaders, new com.aliyun.teautil.models.RuntimeOptions());
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                throw new YmException(err.message);
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                throw new YmException(err.message);
            }

        }
    }

    /**
     * 最大有效期3600L 1小时
     * 修改权限
     * @param jsonObject
     */
    public void updateFileUserPermissions(JSONObject jsonObject,String bookId){

        //判断有没有过期
        String permissions = redisUtil.get(RedisKeyManager.book_permissions_key  + bookId, String.class);
        if(UtilValidate.isNotEmpty(permissions)){
            //没有过期就不需要更新
            return;
        }

        String accessToken = accessTokenService.getAccessToken();

        com.aliyun.dingtalkstorage_2_0.models.UpdatePermissionHeaders updatePermissionHeaders = new com.aliyun.dingtalkstorage_2_0.models.UpdatePermissionHeaders();
        updatePermissionHeaders.xAcsDingtalkAccessToken = accessToken;
        com.aliyun.dingtalkstorage_2_0.models.UpdatePermissionRequest.UpdatePermissionRequestOption option = new com.aliyun.dingtalkstorage_2_0.models.UpdatePermissionRequest.UpdatePermissionRequestOption()
                .setDuration(3600L);
        com.aliyun.dingtalkstorage_2_0.models.UpdatePermissionRequest.UpdatePermissionRequestMembers members0 = new com.aliyun.dingtalkstorage_2_0.models.UpdatePermissionRequest.UpdatePermissionRequestMembers()
                .setType("ORG")
                .setId(corpId)
                .setCorpId(corpId);
        com.aliyun.dingtalkstorage_2_0.models.UpdatePermissionRequest updatePermissionRequest = new com.aliyun.dingtalkstorage_2_0.models.UpdatePermissionRequest()
                .setUnionId(unionId)
                .setRoleId("DOWNLOADER")
                .setMembers(java.util.Arrays.asList(
                        members0
                ))
                .setOption(option);
        try {
            com.aliyun.dingtalkstorage_2_0.Client client = createClient_2();
            UpdatePermissionResponse response = client.updatePermissionWithOptions(jsonObject.getString("uuid"), updatePermissionRequest, updatePermissionHeaders, new RuntimeOptions());
            if(response.getBody().getSuccess()){
                System.out.println("--权限更新成功"+bookId);
                //更新成功
                redisUtil.set(RedisKeyManager.book_permissions_key+bookId, bookId,3500L);

            }
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                log.error("--更新文件权限出现异常:"+err.message,err);
//                throw new YmException(err.message);
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                log.error("--更新文件权限出现异常:"+err.message,err);
//                throw new YmException(err.message);
            }

        }

    }


    /**
     * 查询文件权限
     * @param jsonObject
     * @return
     */
    public JSONObject queryFileUserPermissions(JSONObject jsonObject){
        JSONObject result=null;
        return result;
    }

}
